<!DOCTYPE html>
<html  lang="zh-CN" >
<head>
  <meta charset="UTF-8">
  <meta name="viewport"
    content="width=device-width, initial-scale=1.0, minimum-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <meta name="theme-color" content="#fff" id="theme-color">
  <meta name="description" content="深山磨柴斧，一鸣震江湖">
  <link rel="icon" href="/img/ic_head.jpg">
  <title>020-Android自定义View(15)：Matrix详解(图文)</title>
  
  
  <meta property="og:title" content="020-Android自定义View(15)：Matrix详解(图文)">
  
  
  <meta property="og:url" content="http://example.com/2019/08/16/020-Android%E8%87%AA%E5%AE%9A%E4%B9%89View(15)%EF%BC%9AMatrix%E8%AF%A6%E8%A7%A3(%E5%9B%BE%E6%96%87)/index.html">
  
  
  <meta property="og:img" content="/img/ic_head.jpg">
  
  
  <meta property="og:img" content="深山磨柴斧，一鸣震江湖">
  
  
  <meta property="og:type" content="article">
  <meta property="og:article:published_time" content="2019-08-16">
  <meta property="og:article:modified_time" content="2021-04-14">
  <meta property="og:article:author" content="Cupster">
  
  
  <meta property="og:article:tag" content="Android">
  
  <meta property="og:article:tag" content="Android自定义View">
  
  
  
  
  <script>
    // control reverse button
    var reverseDarkList = {
      dark: 'light',
      light: 'dark'
    };
    var themeColor = {
      dark: '#1c1c1e',
      light: '#fff'
    }
    // get the data of css prefers-color-scheme
    var getCssMediaQuery = function() {
      return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
    };
    // reverse current darkmode setting function
    var reverseDarkModeSetting = function() {
      var setting = localStorage.getItem('user-color-scheme');
      if(reverseDarkList[setting]) {
        setting = reverseDarkList[setting];
      } else if(setting === null) {
        setting = reverseDarkList[getCssMediaQuery()];
      } else {
        return;
      }
      localStorage.setItem('user-color-scheme', setting);
      return setting;
    };
    // apply current darkmode setting
    var setDarkmode = function(mode) {
      var setting = mode || localStorage.getItem('user-color-scheme');
      if(setting === getCssMediaQuery()) {
        document.documentElement.removeAttribute('data-user-color-scheme');
        localStorage.removeItem('user-color-scheme');
        document.getElementById('theme-color').content = themeColor[setting];
      } else if(reverseDarkList[setting]) {
        document.documentElement.setAttribute('data-user-color-scheme', setting);
        document.getElementById('theme-color').content = themeColor[setting];
      } else {
        document.documentElement.removeAttribute('data-user-color-scheme');
        localStorage.removeItem('user-color-scheme');
        document.getElementById('theme-color').content = themeColor[getCssMediaQuery()];
      }
    };
    setDarkmode();
  </script>
  <script>
    function loadScript(url, cb) {
      var script = document.createElement('script');
      script.src = url;
      if (cb) script.onload = cb;
      script.async = true;
      document.body.appendChild(script);
    }
  </script>
  
  <link rel="preload" href="//at.alicdn.com/t/font_1946621_i1kgafibvw.css" as="style" >
  <link rel="preload" href="//at.alicdn.com/t/font_1952792_89b4ac4k4up.css" as="style" >
  
  <link rel="preload" href="/js/lib/lightbox/baguetteBox.min.js" as="script">
  <link rel="preload" href="/js/lib/lightbox/baguetteBox.min.css" as="style" >
  
  
  <link rel="preload" href="/js/lib/lozad.min.js" as="script">
  
  
  
  
  
  
  
  
<link rel="stylesheet" href="/css/main.css">

  
  
<link rel="stylesheet" href="//at.alicdn.com/t/font_1946621_i1kgafibvw.css">

  
  
<link rel="stylesheet" href="//at.alicdn.com/t/font_1952792_89b4ac4k4up.css">

  
  
<link rel="stylesheet" href="/js/lib/lightbox/baguetteBox.min.css">

  
  
  
  
<meta name="generator" content="Hexo 5.4.0"></head>


<body>
  <div class="wrapper">
    
    <nav class="navbar">
  <div class="navbar-logo">
    <span class="navbar-logo-main">
      
      <img class="navbar-logo-img" src="/img/ic_head.jpg" alt="logo">
      
      <span class="navbar-logo-dsc">不负明天</span>
    </span>
  </div>
  <div class="navbar-menu">
    
    <a href="/" class="navbar-menu-item">
    
    首页
    
    </a>
    
    <a href="/archives" class="navbar-menu-item">
    
    归档
    
    </a>
    
    <a href="/tags" class="navbar-menu-item">
    
    标签
    
    </a>
    
    <a href="/categories" class="navbar-menu-item">
    
    分类
    
    </a>
    
    <a href="/about" class="navbar-menu-item">
    
    关于
    
    </a>
    
    <a href="/links" class="navbar-menu-item">
    
    友链
    
    </a>
    
    <a class="navbar-menu-item darknavbar" id="dark"><i class="iconfont icon-weather"></i></a>
    <a class="navbar-menu-item searchnavbar" id="search"><i class="iconfont icon-search" style="font-size: 1.2rem; font-weight: 400;"></i></a>
  </div>
</nav>
    
    <div id="local-search" style="display: none;">
      <input class="navbar-menu-item" id="search-input" placeholder="请输入搜索内容...">
      <div id="search-content"></div>
    </div>
    
    <div class="section-wrap">
      <div class="container">
        <div class="columns">
          <main class="main-column">
<article class="card card-content">
  <header>
    <h1 class="post-title">
      020-Android自定义View(15)：Matrix详解(图文)
    </h1>
  </header>
  <div class="post-meta post-show-meta">
    <time datetime="2019-08-16T04:14:17.000Z">
      <i class="iconfont icon-calendar" style="margin-right: 2px;"></i>
      <span>2019-08-16</span>
    </time>
    
    <span class="dot"></span>
    
    <a href="/categories/Android/" class="post-meta-link">Android</a>
    
    
    
    <span class="dot"></span>
    <span>1.5k 字</span>
    
  </div>
  
  <div class="post-meta post-show-meta" style="margin-top: -10px;">
    <div style="display: flex; align-items: center;">
      <i class="iconfont icon-biaoqian" style="margin-right: 2px; font-size: 1.15rem;"></i>
      
      
        <a href="/tags/Android/" class="post-meta-link">Android</a>
      
      
      <span class="dot"></span>
      
        <a href="/tags/Android自定义View/" class="post-meta-link">Android自定义View</a>
      
    </div>
  </div>
  
  </header>
  <div id="section" class="post-content">
    <p><a target="_blank" rel="noopener" href="https://blog.csdn.net/Cupster/article/details/113516327">【5年Android从零复盘系列之二十】Android自定义View(15)：Matrix详解【转载】</a></p>
<hr />

<h1 id="1-概述"><a href="#1-概述" class="headerlink" title="1.概述"></a>1.概述</h1><p>Android Matrix ，是一个3*3矩阵，用于Android View中处理图形变换。</p>
<h1 id="2-原理"><a href="#2-原理" class="headerlink" title="2.原理"></a>2.原理</h1><h2 id="2-1-Android-Matrix-矩阵图示"><a href="#2-1-Android-Matrix-矩阵图示" class="headerlink" title="2.1 Android Matrix 矩阵图示"></a>2.1 Android Matrix 矩阵图示</h2><img src="https://gitee.com/cupster/picbed/raw/master/uPic/20210128180436_KEXCMp.jpg" / srcset="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20300%20300'%3E%3C/svg%3E" data-src="https://gitee.com/cupster/picbed/raw/master/uPic/20210128180436_KEXCMp.jpg" class="lozad post-image">


<p>功能/作用图示</p>
<img src="https://gitee.com/cupster/picbed/raw/master/uPic/20210128181143_CGF0Io.jpg" / srcset="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20300%20300'%3E%3C/svg%3E" data-src="https://gitee.com/cupster/picbed/raw/master/uPic/20210128181143_CGF0Io.jpg" class="lozad post-image">


<p>其中：</p>
<ol>
<li>MSCALE_X代表x方向的缩放值，MSCALE_Y代表y方向的缩放值；</li>
<li>MSKEW_X、MSKEW_Y分别代表x、y方向的错切系数；</li>
<li>MTRANS_X、MTRANS_Y分别代表x、y方向的平移量；</li>
<li>MPERSP_0、MPERSP_1、MPERSP_2代表透视值。</li>
</ol>
<br />

<h2 id="2-2-数学分析："><a href="#2-2-数学分析：" class="headerlink" title="2.2 数学分析："></a>2.2 数学分析：</h2><p>假定有一个点 ，相对坐标原点顺时针旋转后的情形，同时假定P点离坐标原点的距离为r，如下图</p>
<img src="https://gitee.com/cupster/picbed/raw/master/uPic/20210201110833_dXHWxV.jpg" / srcset="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20300%20300'%3E%3C/svg%3E" data-src="https://gitee.com/cupster/picbed/raw/master/uPic/20210201110833_dXHWxV.jpg" class="lozad post-image">

<p>那么就有：</p>
<img src="https:/ srcset="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20300%20300'%3E%3C/svg%3E" data-src="https://gitee.com/cupster/picbed/raw/master/uPic/20210201110916_36wbj0.jpg" class="lozad post-image"/gitee.com/cupster/picbed/raw/master/uPic/20210201110916_36wbj0.jpg"/>

<p>换做矩阵运算就如下</p>
<img src="https://gitee.com/cupster/picbed/raw/master/uPic/20210201111122_ufR5CR.jpg" / srcset="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20300%20300'%3E%3C/svg%3E" data-src="https://gitee.com/cupster/picbed/raw/master/uPic/20210201111122_ufR5CR.jpg" class="lozad post-image">


<p>可以看到，上面的矩阵四块区域的切分也是因为矩阵乘法的操作决定的，由于这里的乘法运算中:</p>
<ol>
<li>左上角的四个值，可以和x，y值做乘法运算，所以可以影响到旋转等操作</li>
<li>右上角的模块，只能做加法，所以只能影响到平移</li>
<li>右下角的模块主要管z轴，自然就可以进行等比的缩放</li>
<li>左下角的模块一般不去动他，否则会把x，y值加入到z轴中来，会不可控</li>
</ol>
<h1 id="3-基础API使用"><a href="#3-基础API使用" class="headerlink" title="3. 基础API使用"></a>3. 基础API使用</h1><h2 id="3-1-单变换"><a href="#3-1-单变换" class="headerlink" title="3.1 单变换"></a>3.1 单变换</h2><table>
<thead>
<tr>
<th>方法</th>
<th>功能</th>
<th>备注</th>
</tr>
</thead>
<tbody><tr>
<td>Matrix()</td>
<td>构造方法</td>
<td>创建一个单位矩阵</td>
</tr>
<tr>
<td>Matrix(Matrix src)</td>
<td>构造方法</td>
<td>根据参数矩阵，深拷贝方式创建一个新矩阵</td>
</tr>
<tr>
<td>isIdentity()</td>
<td>是否是单位矩阵</td>
<td><img src="https:/ srcset="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20300%20300'%3E%3C/svg%3E" data-src="https://gitee.com/cupster/picbed/raw/master/uPic/20210201112619_vJz0Ty.jpg" class="lozad post-image"/gitee.com/cupster/picbed/raw/master/uPic/20210201112619_vJz0Ty.jpg"/></td>
</tr>
<tr>
<td>isAffine()</td>
<td>是否是仿射矩阵</td>
<td>矩阵最后一行是0,0,1则是仿射矩阵  <br/><img src="https:/ srcset="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20300%20300'%3E%3C/svg%3E" data-src="https://gitee.com/cupster/picbed/raw/master/uPic/20210201112619_vJz0Ty.jpg" class="lozad post-image"/gitee.com/cupster/picbed/raw/master/uPic/20210201112619_vJz0Ty.jpg"/></td>
</tr>
<tr>
<td>rectStaysRect()</td>
<td>判断该矩阵是否可以将一个矩形依然变换为一个矩形。当矩阵是单位矩阵，或者只进行平移，缩放，以及旋转90度的倍数的时候，返回true</td>
<td></td>
</tr>
<tr>
<td>reset()</td>
<td>重置矩阵为单位矩阵</td>
<td><img src="https:/ srcset="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20300%20300'%3E%3C/svg%3E" data-src="https://gitee.com/cupster/picbed/raw/master/uPic/20210201112619_vJz0Ty.jpg" class="lozad post-image"/gitee.com/cupster/picbed/raw/master/uPic/20210201112619_vJz0Ty.jpg"/></td>
</tr>
<tr>
<td>setTranslate(float dx, float dy)</td>
<td>设置平移效果，参数分别是x，y上的平移量</td>
<td>Matrix matrix = newMatrix(); <br/> canvas.drawBitmap(bitmap, matrix, paint);<br/>matrix.setTranslate(100, 1000);<br/>canvas.drawBitmap(bitmap, matrix, paint);</td>
</tr>
<tr>
<td>setScale(float sx, float sy, float px, float py) <br /> <br /> setScale(float sx, float sy)</td>
<td>sx，sy代表了缩放的倍数，px,py代表缩放的中心</td>
<td></td>
</tr>
<tr>
<td>setRotate(float degrees, float px, float py)<br/><br/>setRotate(float degrees)</td>
<td>参数1:旋转角度，px,py代表缩放的中心</td>
<td></td>
</tr>
<tr>
<td>setSinCos(float sinValue, float cosValue, float px, float py)<br/><br/>setSinCos(float sinValue, float cosValue)</td>
<td>sinValue：对应图中的sin值<br/>cosValue：对应cos值<br/>px:中心的x坐标<br/>py：中心的y坐标</td>
<td><img src="https://gitee.com/cupster/picbed/raw/master/uPic/20210201111122_ufR5CR.jpg" / srcset="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20300%20300'%3E%3C/svg%3E" data-src="https://gitee.com/cupster/picbed/raw/master/uPic/20210201111122_ufR5CR.jpg" class="lozad post-image"><br/>顺时针旋转90度，对应的sin和cos分别是1和0<br/>Matrixmatrix = new Matrix();<br/>matrix.setSinCos(1, 0, bitmap.getWidth() / 2, bitmap.getHeight() / 2);<br/>canvas.drawBitmap(bitmap, matrix, paint);</td>
</tr>
<tr>
<td>setSkew(float kx, float ky, float px, float py)<br/><br/>setSkew(float kx, float ky)</td>
<td>kx，ky分别代表了x，y上的错切因子，px，py代表了错切的中心</td>
<td></td>
</tr>
<tr>
<td>setConcat(Matrix a,Matrix b)</td>
<td>当前matrix的值变为a和b的乘积</td>
<td></td>
</tr>
</tbody></table>
<h2 id="3-2-复合变换"><a href="#3-2-复合变换" class="headerlink" title="3.2 复合变换"></a>3.2 复合变换</h2><table>
<thead>
<tr>
<th>方法</th>
<th>功能</th>
<th>备注</th>
</tr>
</thead>
<tbody><tr>
<td>preXXXX:以pre开头，例如preTranslate</td>
<td>前乘复和变换</td>
<td>矩阵前乘<br/>Matrix matrix = new Matrix();<br/>matrix.setTranslate(100, 1000);<br/>matrix.preScale(0.5f, 0.5f);<img  srcset="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20300%20300'%3E%3C/svg%3E" data-src="https://gitee.com/cupster/picbed/raw/master/uPic/20210201135358_mTyKx7.jpg" class="lozad post-image"src="https://gitee.com/cupster/picbed/raw/master/uPic/20210201135358_mTyKx7.jpg"></td>
</tr>
<tr>
<td>postXXXX:以post开头，例如postScale</td>
<td>后乘复和变换</td>
<td>矩阵后乘<br />Matrix matrix = new Matrix();<br/>matrix.setTranslate(100, 1000);<br/>matrix.postScale(0.5f, 0.5f);<img src="https:/ srcset="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20300%20300'%3E%3C/svg%3E" data-src="https://gitee.com/cupster/picbed/raw/master/uPic/20210201140537_LhwifO.jpg" class="lozad post-image"/gitee.com/cupster/picbed/raw/master/uPic/20210201140537_LhwifO.jpg"/> <br/>矩阵前后乘不等价，故结果不一样</td>
</tr>
<tr>
<td>setRectToRect(RectF src, RectF dst, ScaleToFit stf)</td>
<td>将rect变换成rect,ScaleToFit 有如下四个值：<br/><br/>FILL: 可能会变换矩形的长宽比，保证变换和目标矩阵长宽一致。<br/><br/>START:保持坐标变换前矩形的长宽比，并最大限度的填充变换后的矩形。至少有一边和目标矩形重叠。左上对齐。<br/><br/>CENTER: 保持坐标变换前矩形的长宽比，并最大限度的填充变换后的矩形。至少有一边和目标矩形重叠<br/><br/>END:保持坐标变换前矩形的长宽比，并最大限度的填充变换后的矩形。至少有一边和目标矩形重叠。右下对齐。</td>
<td><img src="https:/ srcset="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20300%20300'%3E%3C/svg%3E" data-src="https://gitee.com/cupster/picbed/raw/master/uPic/20210201141547_4BUtX0.jpg" class="lozad post-image"/gitee.com/cupster/picbed/raw/master/uPic/20210201141547_4BUtX0.jpg"/></td>
</tr>
<tr>
<td>setPolyToPoly(float[] src, int srcIndex,float[] dst, int dstIndex,int pointCount)</td>
<td>通过指定的0-4个点，原始坐标以及变化后的坐标，来得到一个变换矩阵。如果指定0个点则没有效果</td>
<td></td>
</tr>
<tr>
<td></td>
<td>指定1个点，可以达到平移效果<br/>float[] src = {0, 0};<br/>int DX = 300;<br/>float[] dst = {0 + DX, 0 + DX};<br/>matrix.setPolyToPoly(src, 0, dst, 0, 1);<br/>canvas.drawBitmap(bitmap, matrix, paint);</td>
<td><img src="https:/ srcset="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20300%20300'%3E%3C/svg%3E" data-src="https://gitee.com/cupster/picbed/raw/master/uPic/20210201142007_kSpDSK.jpg" class="lozad post-image"/gitee.com/cupster/picbed/raw/master/uPic/20210201142007_kSpDSK.jpg"/></td>
</tr>
<tr>
<td></td>
<td>2个点，旋转或者缩放<br/>int bw = bitmap.getWidth();<br/>int bh = bitmap.getHeight();<br/>float[] src = {bw / 2, bh / 2, bw, 0};<br/>float[] dst = {bw / 2, bh / 2, bw / 2 + bh / 2, bh / 2 + bw / 2};<br/>matrix.setPolyToPoly(src, 0, dst, 0, 2);<br/>canvas.drawBitmap(bitmap, matrix, paint);</td>
<td><img src="https:/ srcset="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20300%20300'%3E%3C/svg%3E" data-src="https://gitee.com/cupster/picbed/raw/master/uPic/20210201142104_kp58Oy.jpg" class="lozad post-image"/gitee.com/cupster/picbed/raw/master/uPic/20210201142104_kp58Oy.jpg"/></td>
</tr>
<tr>
<td></td>
<td>3个点，错切<br/>Matrix matrix = new Matrix();<br/>int bw = bitmap.getWidth();<br/>int bh = bitmap.getHeight();<br/>float[] src = {0,0, 0, bh,bw,bh};<br/>float[] dst = {0, 0, 200, bh, bw + 200, bh};<br/>matrix.setPolyToPoly(src, 0, dst, 0, 3);<br/>canvas.drawBitmap(bitmap, matrix, paint);</td>
<td><img src="https:/ srcset="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20300%20300'%3E%3C/svg%3E" data-src="https://gitee.com/cupster/picbed/raw/master/uPic/20210201142246_HvA8ra.jpg" class="lozad post-image"/gitee.com/cupster/picbed/raw/master/uPic/20210201142246_HvA8ra.jpg"/></td>
</tr>
<tr>
<td></td>
<td>4个点，透视<br/>Matrix matrix = new Matrix();<br/>int bw = bitmap.getWidth();<br/>int bh = bitmap.getHeight();<br/>float[] src = {0, 0, 0, bh, bw, bh, bw, 0};<br/>int DX = 100;<br/>float[] dst = {0 + DX, 0, 0, bh, bw, bh, bw - DX, 0};<br/>matrix.setPolyToPoly(src, 0, dst, 0, 4);<br/>canvas.drawBitmap(bitmap, matrix, paint);</td>
<td><img src="https:/ srcset="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20300%20300'%3E%3C/svg%3E" data-src="https://gitee.com/cupster/picbed/raw/master/uPic/20210201142535_LFwdhn.jpg" class="lozad post-image"/gitee.com/cupster/picbed/raw/master/uPic/20210201142535_LFwdhn.jpg"/></td>
</tr>
<tr>
<td>invert(Matrix inverse)</td>
<td>反转当前矩阵<br/>如果能反转就返回true并将反转后的值写入inverse，否则返回false。当前矩阵*inverse=单位矩阵。</td>
<td><img src="https:/ srcset="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20300%20300'%3E%3C/svg%3E" data-src="https://gitee.com/cupster/picbed/raw/master/uPic/20210201142832_Ffb1fz.jpg" class="lozad post-image"/gitee.com/cupster/picbed/raw/master/uPic/20210201142832_Ffb1fz.jpg"/></td>
</tr>
<tr>
<td>mapPoints(float[] dst, int dstIndex, float[] src, int srcIndex,int pointCount)<br/>mapPoints(float[] dst, float[] src)<br/>mapPoints(float[] pts)</td>
<td>映射点的值到指定的数组中，这个方法可以在矩阵变换以后，给出指定点的值。<br/>dst：指定写入的数组<br/>dstIndex：写入的起始索引，x，y两个坐标算作一对，索引的单位是对，也就是经过两个值才加1<br/>src：指定要计算的点<br/>srcIndex：要计算的点的索引<br/>pointCount：需要计算的点的个数，每个点有两个值，x和y。</td>
<td></td>
</tr>
<tr>
<td>mapVectors(float[] dst, int dstIndex, float[] src, int srcIndex,int vectorCount)<br/>mapVectors(float[] dst, float[] src)<br/>mapVectors(float[] vecs)</td>
<td>与mapPoionts基本类似，这里是将一个矩阵作用于一个向量，由于向量的平移前后是相等的，所以这个方法不会对translate相关的方法产生反应，如果只是调用了translate相关的方法，那么得到的值和原本的一致。</td>
<td></td>
</tr>
<tr>
<td>mapRect(RectF dst, RectF src)<br/>mapRect(RectF rect)</td>
<td>返回值即是调用的rectStaysRect()</td>
<td></td>
</tr>
<tr>
<td>mapRadius(float radius)</td>
<td>返回一个圆圈半径的平均值，将matrix作用于一个指定radius半径的圆，随后返回的平均半径</td>
<td></td>
</tr>
</tbody></table>

  </div>
  <div>
  
  <div class="post-note note-warning copyright" style="margin-top: 42px">
    <p><span style="font-weight: bold;">作者：</span><a target="_blank" rel="nofollow noopener noreferrer" href="http://example.com/about">Cupster</a></p>
    <p><span style="font-weight: bold;">文章链接：</span><a target="_blank" rel="nofollow noopener noreferrer" href="http://example.com/2019/08/16/020-Android%E8%87%AA%E5%AE%9A%E4%B9%89View(15)%EF%BC%9AMatrix%E8%AF%A6%E8%A7%A3(%E5%9B%BE%E6%96%87)/">http://example.com/2019/08/16/020-Android%E8%87%AA%E5%AE%9A%E4%B9%89View(15)%EF%BC%9AMatrix%E8%AF%A6%E8%A7%A3(%E5%9B%BE%E6%96%87)/</a></p>
    <p><span style="font-weight: bold;">版权声明：</span>本博客所有文章除特别声明外，均采用<a target="_blank" rel="noopener" href="https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh">CC BY-NC-SA 4.0 协议</a>。转载请注明出处！</p>
  </div>
  
  </div>
</article>
<div class="nav">
  
  <div class="nav-item-prev">
    <a href="/2019/08/22/021-Android动画（1）：视图动画详解(图文)/" class="nav-link">
      <i class="iconfont icon-left nav-prev-icon"></i>
      <div>
        <div class="nav-label">上一篇</div>
        
        <div class="nav-title">021-Android动画（1）：视图动画详解(图文) </div>
        
      </div>
    </a>
  </div>
  
  
  <div class="nav-item-next">
    <a href="/2019/08/12/019-Android自定义View(14)：手势处理库android-gesture-detectors详解(图文)/" class="nav-link">
      <div>
        <div class="nav-label">下一篇</div>
        
        <div class="nav-title">019-Android自定义View(14)：手势处理库android-gesture-detectors详解(图文) </div>
        
      </div>
      <i class="iconfont icon-right nav-next-icon"></i>
    </a>
  </div>
  
</div>

<div class="card card-content toc-card" id="mobiletoc">
  <div class="toc-header"><i class="iconfont icon-menu" style="padding-right: 2px;"></i>目录</div>
<ol class="toc"><li class="toc-item toc-level-1"><a class="toc-link" href="#1-%E6%A6%82%E8%BF%B0"><span class="toc-text">1.概述</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#2-%E5%8E%9F%E7%90%86"><span class="toc-text">2.原理</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#2-1-Android-Matrix-%E7%9F%A9%E9%98%B5%E5%9B%BE%E7%A4%BA"><span class="toc-text">2.1 Android Matrix 矩阵图示</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#2-2-%E6%95%B0%E5%AD%A6%E5%88%86%E6%9E%90%EF%BC%9A"><span class="toc-text">2.2 数学分析：</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#3-%E5%9F%BA%E7%A1%80API%E4%BD%BF%E7%94%A8"><span class="toc-text">3. 基础API使用</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#3-1-%E5%8D%95%E5%8F%98%E6%8D%A2"><span class="toc-text">3.1 单变换</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#3-2-%E5%A4%8D%E5%90%88%E5%8F%98%E6%8D%A2"><span class="toc-text">3.2 复合变换</span></a></li></ol></li></ol>
</div></main>
          <aside class="left-column">
            
            <div class="card card-author">
              
<img src="/img/ic_head.jpg" class="author-img">

<p class="author-name">Cupster</p>
<p class="author-description">深山磨柴斧，一鸣震江湖</p>
<div class="author-message">
  <a class="author-posts-count" href="/archives">
    <span>66</span>
    <span>文章</span>
  </a>
  <a class="author-categories-count" href="/categories">
    <span>5</span>
    <span>分类</span>
  </a>
  <a class="author-tags-count" href="/tags">
    <span>31</span>
    <span>标签</span>
  </a>
</div>

<div class="author-card-society">
  
    <div class="author-card-society-icon">
      <a target="_blank" rel="noopener" href="https://cupster.blog.csdn.net/">
        <i class="iconfont /img/ic_csdn.png society-icon"></i>
      </a>
    </div>
  
</div>

            </div>
            
            <div class="sticky-tablet">
  
  
  <article class="display-when-two-columns spacer">
    <div class="card card-content toc-card">
      <div class="toc-header"><i class="iconfont icon-menu" style="padding-right: 2px;"></i>目录</div>
<ol class="toc"><li class="toc-item toc-level-1"><a class="toc-link" href="#1-%E6%A6%82%E8%BF%B0"><span class="toc-text">1.概述</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#2-%E5%8E%9F%E7%90%86"><span class="toc-text">2.原理</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#2-1-Android-Matrix-%E7%9F%A9%E9%98%B5%E5%9B%BE%E7%A4%BA"><span class="toc-text">2.1 Android Matrix 矩阵图示</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#2-2-%E6%95%B0%E5%AD%A6%E5%88%86%E6%9E%90%EF%BC%9A"><span class="toc-text">2.2 数学分析：</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#3-%E5%9F%BA%E7%A1%80API%E4%BD%BF%E7%94%A8"><span class="toc-text">3. 基础API使用</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#3-1-%E5%8D%95%E5%8F%98%E6%8D%A2"><span class="toc-text">3.1 单变换</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#3-2-%E5%A4%8D%E5%90%88%E5%8F%98%E6%8D%A2"><span class="toc-text">3.2 复合变换</span></a></li></ol></li></ol>
    </div>
  </article>
  
  
  <article class="card card-content categories-widget">
    <div class="categories-card">
  <div class="categories-header"><i class="iconfont icon-fenlei" style="padding-right: 2px;"></i>分类</div>
  <div class="categories-list">
    
      <a href="/categories/Android/">
        <div class="categories-list-item">
          Android
          <span class="categories-list-item-badge">38</span>
        </div>
      </a>
    
      <a href="/categories/Linux/">
        <div class="categories-list-item">
          Linux
          <span class="categories-list-item-badge">6</span>
        </div>
      </a>
    
      <a href="/categories/Dev-Base/">
        <div class="categories-list-item">
          Dev-Base
          <span class="categories-list-item-badge">12</span>
        </div>
      </a>
    
      <a href="/categories/Kotlin/">
        <div class="categories-list-item">
          Kotlin
          <span class="categories-list-item-badge">9</span>
        </div>
      </a>
    
      <a href="/categories/自动化脚本/">
        <div class="categories-list-item">
          自动化脚本
          <span class="categories-list-item-badge">1</span>
        </div>
      </a>
    
  </div>
</div>
  </article>
  
  <article class="card card-content tags-widget">
    <div class="tags-card">
  <div class="tags-header"><i class="iconfont icon-biaoqian" style="padding-right: 2px;"></i>热门标签</div>
  <div class="tags-list">
    
    <a href="/tags/Android/" title="Android"><div class="tags-list-item">Android</div></a>
    
    <a href="/tags/Android自定义View/" title="Android自定义View"><div class="tags-list-item">Android自定义View</div></a>
    
    <a href="/tags/MacOS/" title="MacOS"><div class="tags-list-item">MacOS</div></a>
    
    <a href="/tags/Kotlin/" title="Kotlin"><div class="tags-list-item">Kotlin</div></a>
    
    <a href="/tags/Android持久化/" title="Android持久化"><div class="tags-list-item">Android持久化</div></a>
    
    <a href="/tags/CentOS/" title="CentOS"><div class="tags-list-item">CentOS</div></a>
    
    <a href="/tags/Linux/" title="Linux"><div class="tags-list-item">Linux</div></a>
    
    <a href="/tags/Android事件/" title="Android事件"><div class="tags-list-item">Android事件</div></a>
    
    <a href="/tags/Android基础/" title="Android基础"><div class="tags-list-item">Android基础</div></a>
    
    <a href="/tags/Android手势/" title="Android手势"><div class="tags-list-item">Android手势</div></a>
    
    <a href="/tags/Scrcpy/" title="Scrcpy"><div class="tags-list-item">Scrcpy</div></a>
    
    <a href="/tags/Android动画/" title="Android动画"><div class="tags-list-item">Android动画</div></a>
    
    <a href="/tags/Git/" title="Git"><div class="tags-list-item">Git</div></a>
    
    <a href="/tags/Java/" title="Java"><div class="tags-list-item">Java</div></a>
    
    <a href="/tags/Docker/" title="Docker"><div class="tags-list-item">Docker</div></a>
    
    <a href="/tags/Android-Dialog/" title="Android Dialog"><div class="tags-list-item">Android Dialog</div></a>
    
  </div>
</div>
  </article>
  
  
</div>
          </aside>
          <aside class="right-column">
            <div class="sticky-widescreen">
  
  
  <article class="card card-content toc-card">
    <div class="toc-header"><i class="iconfont icon-menu" style="padding-right: 2px;"></i>目录</div>
<ol class="toc"><li class="toc-item toc-level-1"><a class="toc-link" href="#1-%E6%A6%82%E8%BF%B0"><span class="toc-text">1.概述</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#2-%E5%8E%9F%E7%90%86"><span class="toc-text">2.原理</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#2-1-Android-Matrix-%E7%9F%A9%E9%98%B5%E5%9B%BE%E7%A4%BA"><span class="toc-text">2.1 Android Matrix 矩阵图示</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#2-2-%E6%95%B0%E5%AD%A6%E5%88%86%E6%9E%90%EF%BC%9A"><span class="toc-text">2.2 数学分析：</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#3-%E5%9F%BA%E7%A1%80API%E4%BD%BF%E7%94%A8"><span class="toc-text">3. 基础API使用</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#3-1-%E5%8D%95%E5%8F%98%E6%8D%A2"><span class="toc-text">3.1 单变换</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#3-2-%E5%A4%8D%E5%90%88%E5%8F%98%E6%8D%A2"><span class="toc-text">3.2 复合变换</span></a></li></ol></li></ol>
  </article>
  
  
  <article class="card card-content">
    <div class="recent-posts-card">
  <div class="recent-posts-header"><i class="iconfont icon-wenzhang_huaban" style="padding-right: 2px;"></i>最近文章</div>
  <div class="recent-posts-list">
    
      <div class="recent-posts-item">
        <div class="recent-posts-item-title">2021-03-02</div>
        <a href="/2021/03/02/Git commit规范/"><div class="recent-posts-item-content">Git commit规范</div></a>
      </div>
    
      <div class="recent-posts-item">
        <div class="recent-posts-item-title">2021-02-16</div>
        <a href="/2021/02/16/AutoJS一文精通AutoJS脚本教程详解/"><div class="recent-posts-item-content">AutoJS一文精通AutoJS脚本教程详解</div></a>
      </div>
    
      <div class="recent-posts-item">
        <div class="recent-posts-item-title">2021-01-21</div>
        <a href="/2021/01/21/架构师进阶：注解Annotation全解/"><div class="recent-posts-item-content">架构师进阶：注解Annotation全解</div></a>
      </div>
    
      <div class="recent-posts-item">
        <div class="recent-posts-item-title">2021-01-06</div>
        <a href="/2021/01/06/ConstraintLayout详解/"><div class="recent-posts-item-content">ConstraintLayout详解</div></a>
      </div>
    
  </div>
</div>
  </article>
  
  
</div>
          </aside>
        </div>
      </div>
    </div>
  </div>
  
  <footer class="footer">
  <div class="footer-container">
    <div>
      <div class="footer-dsc">
        <span>Copyright ©
          
          2020 -
          
          2021
        </span>
        &nbsp;
        <a href="/" class="footer-link">不负明天 </a>
      </div>
    </div>

    
    <div class="footer-dsc">
      
      Powered by
      <a href="https://hexo.io/" class="footer-link" target="_blank" rel="nofollow noopener noreferrer">&nbsp;Hexo </a>
      
      
      <span>&nbsp;|&nbsp;</span>
      
      
      Theme -
      <a href="https://github.com/theme-kaze" class="footer-link" target="_blank"
        rel="nofollow noopener noreferrer">&nbsp;Kaze</a>
      
    </div>
    
    
    
    
      <div class="footer-dsc">
        
        本站总访问量686<span id="busuanzi_value_site_pv"></span>次
        
        
        <span>&nbsp;|&nbsp;</span>
        
        
        本站总访客数219<span id="busuanzi_value_site_uv"></span>次
        
      </div>
      
    
</footer>
  <a role="button" id="scrollbutton" class="basebutton"  aria-label="回到顶部">
  <i class="iconfont icon-arrowleft button-icon"></i>
</a>
<a role="button" id="menubutton" class="basebutton">
  <i class="iconfont icon-menu button-icon"></i>
</a>
<a role="button" id="popbutton" class="basebutton" aria-label="控制中心">
  <i class="iconfont icon-expand button-icon"></i>
</a>
<a role="button" id="darkbutton" class="basebutton darkwidget" aria-label="夜色模式">
  <i class="iconfont icon-weather button-icon"></i>
</a>
<a role="button" id="searchbutton" class="basebutton searchwidget" aria-label="搜索">
  <i class="iconfont icon-search button-icon"></i>
</a>

  
  
  
  <script>
  var addImgLayout = function () {
    var img = document.querySelectorAll('.post-content img');
    var i;
    for (i = 0; i < img.length; i++) {
      var wrapper = document.createElement('a');
      wrapper.setAttribute('href', img[i].getAttribute('data-src'));
      wrapper.setAttribute('aria-label', 'illustration');
      wrapper.style.cssText = 'width: 100%; display: flex; justify-content: center;';
      if (img[i].alt) wrapper.dataset.caption = img[i].alt;
      wrapper.dataset.nolink = true;
      img[i].before(wrapper);
      wrapper.append(img[i]);
      var divWrap = document.createElement('div');
      divWrap.classList.add('gallery');
      wrapper.before(divWrap);
      divWrap.append(wrapper);
    }
    baguetteBox.run('.gallery');
  }
</script>
<script>loadScript("/js/lib/lightbox/baguetteBox.min.js", addImgLayout)</script>
  
  
  
<script src="/js/main.js"></script>

  
  <script>loadScript("/js/lib/busuanzi.min.js")</script>
  
  
  <script>
    var addLazyload = function () {
      var observer = lozad('.lozad', {
        load: function (el) {
          el.srcset = el.getAttribute('data-src');
        },
        loaded: function (el) {
          el.classList.add('loaded');
        }
      });
      observer.observe();
    }
  </script>
  <script>loadScript("/js/lib/lozad.min.js", addLazyload)</script>
  
  
</body>

</html>